//
// Created by francklinson on 2021/6/17.
//
#include <unordered_map>
#include <string>
#include <iostream>

using namespace std;
/**
 * 自动机  根据当前状态自动跳转
 */
class Solution {
public:
    struct EnumClassHash {
        template<class T>
        std::size_t operator()(T t) const {
            return static_cast<std::size_t >(t); // 自定义哈希函数
        }
    };

    enum State {
        STATE_INITIAL,
        STATE_INT_SIGN,
        STATE_INTEGER,
        STATE_POINT,
        STATE_POINT_WITHOUT_INT,
        STATE_FRACTION,
        STATE_EXP,
        STATE_EXP_SIGN,
        STATE_EXP_NUMBER,
        STATE_END
    };

    enum CharType {
        CHAR_NUMBER,
        CHAR_EXP,
        CHAR_POINT,
        CHAR_SIGN,
        CHAR_ILLEGAL
    };

    CharType toCharType(char ch) {
        if (ch >= '0' && ch <= '9') {
            return CHAR_NUMBER;
        } else if (ch == 'e' || ch == 'E') {
            return CHAR_EXP;
        } else if (ch == '.') {
            return CHAR_POINT;
        } else if (ch == '+' || ch == '-') {
            return CHAR_SIGN;
        } else {
            return CHAR_ILLEGAL;
        }
    }

    bool isNumber(string s) {
        unordered_map<State, State, EnumClassHash> a;
        unordered_map<State, unordered_map<CharType, State, EnumClassHash>, EnumClassHash> transfer{
                {
                        STATE_INITIAL,           {
                                                         {CHAR_NUMBER, STATE_INTEGER},
                                                         {CHAR_POINT, STATE_POINT_WITHOUT_INT},
                                                         {CHAR_SIGN,  STATE_INT_SIGN}
                                                 }
                },
                {
                        STATE_INT_SIGN,          {
                                                         {CHAR_NUMBER, STATE_INTEGER},
                                                         {CHAR_POINT, STATE_POINT_WITHOUT_INT}
                                                 }
                },
                {
                        STATE_INTEGER,           {
                                                         {CHAR_NUMBER, STATE_INTEGER},
                                                         {CHAR_EXP,   STATE_EXP},
                                                         {CHAR_POINT, STATE_POINT}
                                                 }
                },
                {
                        STATE_POINT,             {
                                                         {CHAR_NUMBER, STATE_FRACTION},
                                                         {CHAR_EXP,   STATE_EXP}
                                                 }
                },
                {
                        STATE_POINT_WITHOUT_INT, {
                                                         {CHAR_NUMBER, STATE_FRACTION}
                                                 }
                },
                {
                        STATE_FRACTION,
                                                 {
                                                         {CHAR_NUMBER, STATE_FRACTION},
                                                         {CHAR_EXP,   STATE_EXP}
                                                 }
                },
                {
                        STATE_EXP,
                                                 {
                                                         {CHAR_NUMBER, STATE_EXP_NUMBER},
                                                         {CHAR_SIGN,  STATE_EXP_SIGN}
                                                 }
                },
                {
                        STATE_EXP_SIGN,          {
                                                         {CHAR_NUMBER, STATE_EXP_NUMBER}
                                                 }
                },
                {
                        STATE_EXP_NUMBER,        {
                                                         {CHAR_NUMBER, STATE_EXP_NUMBER}
                                                 }
                }
        };

        int len = (int) s.length();
        State st = STATE_INITIAL; // 初始状态

        for (int i = 0; i < len; i++) {
            CharType typ = toCharType(s[i]); // 判断当前的字符类型
            if (transfer[st].find(typ) == transfer[st].end()) { // 没有对应的下一个状态
                return false;
            } else {
                st = transfer[st][typ];
            }
        }
        return st == STATE_INTEGER || st == STATE_POINT || st == STATE_FRACTION || st == STATE_EXP_NUMBER ||
               st == STATE_END;
    }
};

int main() {
    Solution sol;
    cout << sol.isNumber("1e55") << endl;
    return 0;
}